#include "RecordDataHelper.h"

#include <QHeaderView>

#include "../common/ConstData.h"
#include "../sql/database.h"
#include "../sql/errorlog.h"
#include "../sql/upload_database.h"

void RecordDataHelper::setupTableHeaders(QTableWidget *tableWidget, RecordType recordType)
{
    if (!tableWidget) return;

    switch (recordType) {
        case RecordType::DeviceData:
            setupDeviceDataHeaders(tableWidget);
            break;
        case RecordType::UploadData:
            setupUploadRecordHeaders(tableWidget);
            break;
        case RecordType::ErrorData:
            setupErrorLogHeaders(tableWidget);
            break;
        case RecordType::CalibrationData:
            setupCalibrationHeaders(tableWidget);
            break;
        case RecordType::InspectionData:
            setupInspectionHeaders(tableWidget);
            break;
        case RecordType::SpikeRecoveryData:
            setupSpikeRecoveryHeaders(tableWidget);
            break;
    }
}

void RecordDataHelper::loadPageData(QTableWidget *tableWidget, RecordType recordType,
                                    int currentPage, int pageSize, const QDate &queryDate,
                                    const QString &deviceName)
{
    if (!tableWidget) return;

    // 清空表格内容
    tableWidget->clearContents();
    tableWidget->setRowCount(0);

    // 设置表头
    setupTableHeaders(tableWidget, recordType);

    // 根据记录类型加载数据
    switch (recordType) {
        case RecordType::DeviceData:
            loadDeviceData(tableWidget, currentPage, pageSize, queryDate);
            break;
        case RecordType::UploadData:
            loadUploadRecordData(tableWidget, currentPage, pageSize, queryDate);
            break;
        case RecordType::ErrorData:
            loadErrorLogData(tableWidget, currentPage, pageSize, queryDate, deviceName);
            break;
        case RecordType::CalibrationData:
            loadCalibrationData(tableWidget, currentPage, pageSize, queryDate, deviceName);
            break;
        case RecordType::InspectionData:
            loadInspectionData(tableWidget, currentPage, pageSize, queryDate, deviceName);
            break;
        case RecordType::SpikeRecoveryData:
            loadSpikeRecoveryData(tableWidget, currentPage, pageSize, queryDate, deviceName);
            break;
    }
}

int RecordDataHelper::getTotalRecords(RecordType recordType, const QDate &queryDate,
                                      const QString &deviceName)
{
    switch (recordType) {
        case RecordType::DeviceData:
            return Database::getTotalRecords(queryDate);
        case RecordType::UploadData:
            return UploadDatabase::getTotalUploadRecords(queryDate);
        case RecordType::ErrorData:
            return ErrorLog::getTotalRecords(queryDate, deviceName);
        case RecordType::CalibrationData:
            return Database::getCalibrationRecordsCount(queryDate, deviceName);
        case RecordType::InspectionData:
            return Database::getInspectionRecordsCount(queryDate, deviceName);
        case RecordType::SpikeRecoveryData:
            return Database::getSpikeRecoveryRecordsCount(queryDate, deviceName);
        default:
            return 0;
    }
}

void RecordDataHelper::setupDeviceDataHeaders(QTableWidget *tableWidget)
{
    QStringList headers;
    headers << "时间";  // 第一个表头是 timestamp

    for (const QString &name : DEVICE_NAMES) {
        if (DEVICE_MAP[name].isShowData) {
            headers << name;
        }
    }

    tableWidget->setColumnCount(headers.size());
    tableWidget->setHorizontalHeaderLabels(headers);
    tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    tableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed);  // 固定第一列
}

void RecordDataHelper::loadDeviceData(QTableWidget *tableWidget, int currentPage, int pageSize,
                                      const QDate &queryDate)
{
    // 使用Database类的分页查询方法
    QVector<QVariantMap> data = Database::queryByPage(currentPage, pageSize, queryDate);

    int rowIdx = 0;
    for (const QVariantMap &record : data) {
        tableWidget->insertRow(rowIdx);

        // 时间戳 (第0列)
        QTableWidgetItem *itemTimestamp =
            new QTableWidgetItem(record.value("timestamp").toString());
        itemTimestamp->setTextAlignment(Qt::AlignCenter);
        tableWidget->setItem(rowIdx, 0, itemTimestamp);

        // 模块数据 (从第1列开始)
        int colIdx = 1;
        for (const QString &name : DEVICE_NAMES) {
            if (!DEVICE_MAP[name].isShowData) continue;

            QVariant moduleValue = record.value(name);
            QString displayText;
            if (moduleValue.isNull()) {
                displayText = "- -";
            } else {
                displayText = QString::number(moduleValue.toDouble(), 'f', 3);
            }

            QTableWidgetItem *itemModuleData = new QTableWidgetItem(displayText);
            itemModuleData->setTextAlignment(Qt::AlignCenter);
            tableWidget->setItem(rowIdx, colIdx, itemModuleData);
            colIdx++;
        }

        rowIdx++;
    }
}

void RecordDataHelper::setupUploadRecordHeaders(QTableWidget *tableWidget)
{
    QStringList headers;
    headers << "上传时间"
            << "服务器"
            << "状态"
            << "数据包";

    tableWidget->setColumnCount(headers.size());
    tableWidget->setHorizontalHeaderLabels(headers);
    tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
    tableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed);  // 固定第一列
}

void RecordDataHelper::loadUploadRecordData(QTableWidget *tableWidget, int currentPage,
                                            int pageSize, const QDate &queryDate)
{
    // 使用UploadDatabase类的分页查询方法
    QVector<QVariantMap> data =
        UploadDatabase::queryUploadRecordsByPage(currentPage, pageSize, queryDate);

    int rowIdx = 0;
    for (const QVariantMap &record : data) {
        tableWidget->insertRow(rowIdx);

        int colIdx = 0;

        // 上传时间
        QTableWidgetItem *timeItem = new QTableWidgetItem(record.value("upload_time").toString());
        timeItem->setTextAlignment(Qt::AlignCenter);
        tableWidget->setItem(rowIdx, colIdx++, timeItem);

        // 服务器信息
        QString serverInfo = QString("%1:%2")
                                 .arg(record.value("server_ip").toString())
                                 .arg(record.value("server_port").toInt());
        QTableWidgetItem *serverItem = new QTableWidgetItem(serverInfo);
        serverItem->setTextAlignment(Qt::AlignCenter);
        tableWidget->setItem(rowIdx, colIdx++, serverItem);

        // 状态
        QTableWidgetItem *statusItem = new QTableWidgetItem(record.value("status_text").toString());
        statusItem->setTextAlignment(Qt::AlignCenter);
        tableWidget->setItem(rowIdx, colIdx++, statusItem);

        // 数据包
        QString dataContent = record.value("data_content").toString();
        QTableWidgetItem *dataItem = new QTableWidgetItem(dataContent);
        dataItem->setTextAlignment(Qt::AlignCenter);
        tableWidget->setItem(rowIdx, colIdx++, dataItem);

        rowIdx++;
    }
}

void RecordDataHelper::setupErrorLogHeaders(QTableWidget *tableWidget)
{
    QStringList headers;
    headers << "设备名称"
            << "错误信息"
            << "记录时间";

    tableWidget->setColumnCount(headers.size());
    tableWidget->setHorizontalHeaderLabels(headers);
    tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    tableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed);  // 固定第一列
}

void RecordDataHelper::loadErrorLogData(QTableWidget *tableWidget, int currentPage, int pageSize,
                                        const QDate &queryDate, const QString &deviceName)
{
    QVector<QVariantMap> data = ErrorLog::queryByPage(currentPage, pageSize, queryDate, deviceName);

    int rowIdx = 0;
    for (const QVariantMap &record : data) {
        tableWidget->insertRow(rowIdx);

        int colIdx = 0;

        // 设备名称
        QTableWidgetItem *deviceItem = new QTableWidgetItem(record.value("device_name").toString());
        deviceItem->setTextAlignment(Qt::AlignCenter);
        tableWidget->setItem(rowIdx, colIdx++, deviceItem);

        // 错误信息
        QTableWidgetItem *errorItem =
            new QTableWidgetItem(record.value("error_message").toString());
        errorItem->setTextAlignment(Qt::AlignCenter);
        tableWidget->setItem(rowIdx, colIdx++, errorItem);

        // 记录时间
        QTableWidgetItem *timeItem = new QTableWidgetItem(record.value("timestamp").toString());
        timeItem->setTextAlignment(Qt::AlignCenter);
        tableWidget->setItem(rowIdx, colIdx++, timeItem);
        rowIdx++;
    }
}

void RecordDataHelper::setupCalibrationHeaders(QTableWidget *tableWidget)
{
    QStringList headers;
    headers << "设备名称"
            << "校准类型"
            << "标准浓度"
            << "信号值"
            << "吸光度"
            << "校准时间"
            << "记录时间";

    tableWidget->setColumnCount(headers.size());
    tableWidget->setHorizontalHeaderLabels(headers);
    tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    tableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed);
}

void RecordDataHelper::loadCalibrationData(QTableWidget *tableWidget, int currentPage, int pageSize,
                                           const QDate &queryDate, const QString &deviceName)
{
    QVector<QVariantMap> data =
        Database::queryCalibrationRecordsByPage(currentPage, pageSize, queryDate, deviceName);

    int rowIdx = 0;
    for (const QVariantMap &record : data) {
        tableWidget->insertRow(rowIdx);

        int colIdx = 0;

        // 设备名称
        QTableWidgetItem *deviceItem = new QTableWidgetItem(record.value("device_name").toString());
        deviceItem->setTextAlignment(Qt::AlignCenter);
        tableWidget->setItem(rowIdx, colIdx++, deviceItem);

        // 校准类型
        QString calibType = record.value("calib_type").toString();
        QString calibTypeText = (calibType == "standard_1") ? "标一校准" : "标二校准";
        QTableWidgetItem *typeItem = new QTableWidgetItem(calibTypeText);
        typeItem->setTextAlignment(Qt::AlignCenter);
        tableWidget->setItem(rowIdx, colIdx++, typeItem);

        // 标准浓度
        QString concentrationText =
            QString::number(record.value("standard_concentration").toDouble(), 'f', 3);
        QTableWidgetItem *concItem = new QTableWidgetItem(concentrationText);
        concItem->setTextAlignment(Qt::AlignCenter);
        tableWidget->setItem(rowIdx, colIdx++, concItem);

        // 信号值
        QString signalText = QString::number(record.value("signal_value").toDouble(), 'f', 3);
        QTableWidgetItem *signalItem = new QTableWidgetItem(signalText);
        signalItem->setTextAlignment(Qt::AlignCenter);
        tableWidget->setItem(rowIdx, colIdx++, signalItem);

        // 吸光度
        QString absorbanceText = QString::number(record.value("absorbance").toDouble(), 'f', 3);
        QTableWidgetItem *absorbanceItem = new QTableWidgetItem(absorbanceText);
        absorbanceItem->setTextAlignment(Qt::AlignCenter);
        tableWidget->setItem(rowIdx, colIdx++, absorbanceItem);

        // 校准时间
        QTableWidgetItem *calibTimeItem =
            new QTableWidgetItem(record.value("calibration_time").toString());
        calibTimeItem->setTextAlignment(Qt::AlignCenter);
        tableWidget->setItem(rowIdx, colIdx++, calibTimeItem);

        // 创建时间
        QTableWidgetItem *createTimeItem =
            new QTableWidgetItem(record.value("created_at").toString());
        createTimeItem->setTextAlignment(Qt::AlignCenter);
        tableWidget->setItem(rowIdx, colIdx++, createTimeItem);

        rowIdx++;
    }
}

void RecordDataHelper::setupInspectionHeaders(QTableWidget *tableWidget)
{
    QStringList headers;
    headers << "设备名称"
            << "核查类型"
            << "标准浓度"
            << "测量浓度"
            << "测量时间"
            << "记录时间";

    tableWidget->setColumnCount(headers.size());
    tableWidget->setHorizontalHeaderLabels(headers);
    tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    tableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed);
}

void RecordDataHelper::loadInspectionData(QTableWidget *tableWidget, int currentPage, int pageSize,
                                          const QDate &queryDate, const QString &deviceName)
{
    QVector<QVariantMap> data =
        Database::queryInspectionRecordsByPage(currentPage, pageSize, queryDate, deviceName);

    int rowIdx = 0;
    for (const QVariantMap &record : data) {
        tableWidget->insertRow(rowIdx);

        int colIdx = 0;

        // 设备名称
        QTableWidgetItem *deviceItem = new QTableWidgetItem(record.value("device_name").toString());
        deviceItem->setTextAlignment(Qt::AlignCenter);
        tableWidget->setItem(rowIdx, colIdx++, deviceItem);

        // 核查类型
        QString recordType = record.value("record_type").toString();
        QString recordTypeText = (recordType == "zero_check") ? "零点核查" : "标液核查";
        QTableWidgetItem *typeItem = new QTableWidgetItem(recordTypeText);
        typeItem->setTextAlignment(Qt::AlignCenter);
        tableWidget->setItem(rowIdx, colIdx++, typeItem);

        // 标准浓度
        QString stdConcText =
            QString::number(record.value("standard_concentration").toDouble(), 'f', 3);
        QTableWidgetItem *stdConcItem = new QTableWidgetItem(stdConcText);
        stdConcItem->setTextAlignment(Qt::AlignCenter);
        tableWidget->setItem(rowIdx, colIdx++, stdConcItem);

        // 测量浓度
        QString measConcText =
            QString::number(record.value("measured_concentration").toDouble(), 'f', 3);
        QTableWidgetItem *measConcItem = new QTableWidgetItem(measConcText);
        measConcItem->setTextAlignment(Qt::AlignCenter);
        tableWidget->setItem(rowIdx, colIdx++, measConcItem);

        // 测量时间
        QTableWidgetItem *measTimeItem =
            new QTableWidgetItem(record.value("measured_time").toString());
        measTimeItem->setTextAlignment(Qt::AlignCenter);
        tableWidget->setItem(rowIdx, colIdx++, measTimeItem);

        // 创建时间
        QTableWidgetItem *createTimeItem =
            new QTableWidgetItem(record.value("created_at").toString());
        createTimeItem->setTextAlignment(Qt::AlignCenter);
        tableWidget->setItem(rowIdx, colIdx++, createTimeItem);

        rowIdx++;
    }
}

void RecordDataHelper::setupSpikeRecoveryHeaders(QTableWidget *tableWidget)
{
    QStringList headers;
    headers << "设备名称"
            << "原始水样浓度"
            << "加标水样浓度"
            << "加标回收率(%)"
            << "测试时间"
            << "记录时间";

    tableWidget->setColumnCount(headers.size());
    tableWidget->setHorizontalHeaderLabels(headers);
    tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    tableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed);
}

void RecordDataHelper::loadSpikeRecoveryData(QTableWidget *tableWidget, int currentPage,
                                             int pageSize, const QDate &queryDate,
                                             const QString &deviceName)
{
    QVector<QVariantMap> data =
        Database::querySpikeRecoveryRecordsByPage(currentPage, pageSize, queryDate, deviceName);

    int rowIdx = 0;
    for (const QVariantMap &record : data) {
        tableWidget->insertRow(rowIdx);

        int colIdx = 0;

        // 设备名称
        QTableWidgetItem *deviceItem = new QTableWidgetItem(record.value("device_name").toString());
        deviceItem->setTextAlignment(Qt::AlignCenter);
        tableWidget->setItem(rowIdx, colIdx++, deviceItem);

        // 原始水样浓度
        QString originalConcText =
            QString::number(record.value("original_concentration").toDouble(), 'f', 3);
        QTableWidgetItem *originalConcItem = new QTableWidgetItem(originalConcText);
        originalConcItem->setTextAlignment(Qt::AlignCenter);
        tableWidget->setItem(rowIdx, colIdx++, originalConcItem);

        // 加标水样浓度
        QString spikedConcText =
            QString::number(record.value("spiked_concentration").toDouble(), 'f', 3);
        QTableWidgetItem *spikedConcItem = new QTableWidgetItem(spikedConcText);
        spikedConcItem->setTextAlignment(Qt::AlignCenter);
        tableWidget->setItem(rowIdx, colIdx++, spikedConcItem);

        // 加标回收率
        QString recoveryRateText =
            QString::number(record.value("recovery_rate").toDouble(), 'f', 2);
        QTableWidgetItem *recoveryRateItem = new QTableWidgetItem(recoveryRateText);
        recoveryRateItem->setTextAlignment(Qt::AlignCenter);
        tableWidget->setItem(rowIdx, colIdx++, recoveryRateItem);

        // 测试时间
        QTableWidgetItem *testTimeItem = new QTableWidgetItem(record.value("test_time").toString());
        testTimeItem->setTextAlignment(Qt::AlignCenter);
        tableWidget->setItem(rowIdx, colIdx++, testTimeItem);

        // 记录创建时间
        QTableWidgetItem *createTimeItem =
            new QTableWidgetItem(record.value("created_at").toString());
        createTimeItem->setTextAlignment(Qt::AlignCenter);
        tableWidget->setItem(rowIdx, colIdx++, createTimeItem);

        rowIdx++;
    }
}

bool RecordDataHelper::exportToCSV(const QString &filePath, RecordType recordType,
                                   const QDate &queryDate, const QString &deviceName)
{
    QFile file(filePath);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        qDebug() << "无法打开文件进行写入:" << filePath;
        return false;
    }

    QTextStream out(&file);
    out.setCodec("UTF-8");

    // 创建临时表格组件获取表头
    QTableWidget tempTable;
    setupTableHeaders(&tempTable, recordType);

    // 写入CSV表头
    QStringList headers;
    for (int col = 0; col < tempTable.columnCount(); ++col) {
        QTableWidgetItem *headerItem = tempTable.horizontalHeaderItem(col);
        if (headerItem) {
            headers << headerItem->text();
        }
    }
    out << headers.join(",") << "\n";

    // 根据记录类型导出对应的数据
    switch (recordType) {
        case RecordType::DeviceData:
            return exportDeviceDataToCSV(out, queryDate, headers);
        case RecordType::UploadData:
            return exportUploadDataToCSV(out, queryDate, headers);
        case RecordType::ErrorData:
            return exportErrorDataToCSV(out, queryDate, deviceName, headers);
        case RecordType::CalibrationData:
            return exportCalibrationDataToCSV(out, queryDate, deviceName, headers);
        case RecordType::InspectionData:
            return exportInspectionDataToCSV(out, queryDate, deviceName, headers);
        case RecordType::SpikeRecoveryData:
            return exportSpikeRecoveryDataToCSV(out, queryDate, deviceName, headers);
        default:
            return false;
    }
}

bool RecordDataHelper::exportDeviceDataToCSV(QTextStream &out, const QDate &queryDate,
                                             const QStringList &headers)
{
    // 获取所有数据（不分页）
    QVector<QVariantMap> data = Database::queryByDate(queryDate);

    // 写入数据行
    for (const QVariantMap &record : data) {
        QStringList rowData;
        rowData << record.value("timestamp").toString();

        for (const QString &name : DEVICE_NAMES) {
            if (!DEVICE_MAP[name].isShowData) continue;

            QVariant moduleValue = record.value(name);
            if (moduleValue.isNull()) {
                rowData << "";
            } else {
                rowData << QString::number(moduleValue.toDouble(), 'f', 3);
            }
        }
        out << rowData.join(",") << "\n";
    }

    return true;
}

bool RecordDataHelper::exportUploadDataToCSV(QTextStream &out, const QDate &queryDate,
                                             const QStringList &headers)
{
    // 获取所有上传记录数据
    QVector<QVariantMap> data = UploadDatabase::queryUploadRecordsByDate(queryDate);

    // 写入数据行
    for (const QVariantMap &record : data) {
        QStringList rowData;
        rowData << record.value("upload_time").toString();
        rowData << QString("%1:%2")
                       .arg(record.value("server_ip").toString())
                       .arg(record.value("server_port").toInt());
        rowData << record.value("status_text").toString();
        rowData << record.value("data_content").toString();
        out << rowData.join(",") << "\n";
    }

    return true;
}

bool RecordDataHelper::exportErrorDataToCSV(QTextStream &out, const QDate &queryDate,
                                            const QString &deviceName, const QStringList &headers)
{
    // 获取所有错误记录数据
    QVector<QVariantMap> data = ErrorLog::queryByDate(queryDate, deviceName);

    // 写入数据行
    for (const QVariantMap &record : data) {
        QStringList rowData;
        rowData << record.value("device_name").toString();
        rowData << record.value("error_message").toString();
        rowData << record.value("timestamp").toString();
        out << rowData.join(",") << "\n";
    }

    return true;
}

bool RecordDataHelper::exportCalibrationDataToCSV(QTextStream &out, const QDate &queryDate,
                                                  const QString &deviceName,
                                                  const QStringList &headers)
{
    // 获取所有校准记录数据
    QVector<QVariantMap> data = Database::queryCalibrationRecords(queryDate, deviceName);

    // 写入数据行
    for (const QVariantMap &record : data) {
        QStringList rowData;
        rowData << record.value("device_name").toString();
        rowData << record.value("calib_type").toString();
        rowData << QString::number(record.value("standard_concentration").toDouble(), 'f', 3);
        rowData << QString::number(record.value("signal_value").toDouble(), 'f', 3);
        rowData << QString::number(record.value("absorbance").toDouble(), 'f', 6);
        rowData << record.value("calibration_time").toString();
        rowData << record.value("created_at").toString();
        out << rowData.join(",") << "\n";
    }

    return true;
}

bool RecordDataHelper::exportInspectionDataToCSV(QTextStream &out, const QDate &queryDate,
                                                 const QString &deviceName,
                                                 const QStringList &headers)
{
    // 获取所有核查记录数据
    QVector<QVariantMap> data = Database::queryInspectionRecords(queryDate, deviceName);

    // 写入数据行
    for (const QVariantMap &record : data) {
        QStringList rowData;
        rowData << record.value("device_name").toString();
        rowData << record.value("record_type").toString();
        rowData << QString::number(record.value("standard_concentration").toDouble(), 'f', 3);
        rowData << QString::number(record.value("measured_concentration").toDouble(), 'f', 3);
        rowData << record.value("measured_time").toString();
        rowData << record.value("created_at").toString();
        out << rowData.join(",") << "\n";
    }

    return true;
}

bool RecordDataHelper::exportSpikeRecoveryDataToCSV(QTextStream &out, const QDate &queryDate,
                                                    const QString &deviceName,
                                                    const QStringList &headers)
{
    // 获取所有加标回收记录数据
    QVector<QVariantMap> data = Database::querySpikeRecoveryRecords(queryDate, deviceName);

    // 写入数据行
    for (const QVariantMap &record : data) {
        QStringList rowData;
        rowData << record.value("device_name").toString();
        rowData << QString::number(record.value("original_concentration").toDouble(), 'f', 3);
        rowData << QString::number(record.value("spiked_concentration").toDouble(), 'f', 3);
        rowData << QString::number(record.value("recovery_rate").toDouble(), 'f', 2);
        rowData << record.value("test_time").toString();
        rowData << record.value("created_at").toString();
        out << rowData.join(",") << "\n";
    }

    return true;
}